// 使用C语言标准IO函数发送邮件
// socat -v OPENSSL:smtp.qq.com:465 EXEC:./automailer

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define SMTP_SENDER      "sender@example.com"
#define SMTP_RECIPIENT   "recipient@example.com"
#define EMAIL_SUBJECT    "test mail"
#define EMAIL_BODY       "这是一封由程序自动发送的测试邮件\n第二行内容"

// Base64编码后的认证信息（通过外部工具生成）
#define B64_USERNAME     "dXNlcm5hbWU="  // echo -n "username" | base64
#define B64_PASSWORD     "cGFzc3dvcmQ="  // echo -n "password" | base64

void read_response(int expected_code)
{
    char buffer[1024];
    while (fgets(buffer, sizeof(buffer), stdin)) {
        if (strlen(buffer) >= 4 && 
            isdigit(buffer[0]) && isdigit(buffer[1]) && isdigit(buffer[2])) {
            int code = atoi(buffer);
            char sep = buffer[3];
            
            if (code == expected_code && sep == ' ') return;
            else if (code == expected_code && sep == '-') continue;
            else {
                fprintf(stderr, "[ERROR] 预期响应码 %d，实际收到：%d\n", expected_code, code);
                exit(EXIT_FAILURE);
            }
        }
    }
}

int main()
{
    // 设置标准输出为行缓冲
    setlinebuf(stdout);
    // SMTP协议交互流程
    read_response(220);  // 等待服务器问候

    // EHLO握手
    printf("HELO localhost\r\n");
    read_response(250);

    // 认证流程
    printf("AUTH LOGIN\r\n");
    read_response(334);  // 期待"VXNlcm5hbWU6"（Username提示）

    printf("%s\r\n", B64_USERNAME);
    read_response(334);  // 期待"UGFzc3dvcmQ6"（Password提示）

    printf("%s\r\n", B64_PASSWORD);
    read_response(235);  // 认证成功

    // 邮件传输
    printf("MAIL FROM:<%s>\r\n", SMTP_SENDER);
    read_response(250);

    printf("RCPT TO:<%s>\r\n", SMTP_RECIPIENT);
    read_response(250);

    printf("DATA\r\n");
    read_response(354);  // 开始数据输入

    // 邮件头
    printf("From: Auto Mailer <%s>\r\n", SMTP_SENDER);
    printf("To: <%s>\r\n", SMTP_RECIPIENT);
    printf("Subject: %s\r\n", EMAIL_SUBJECT);
    printf("MIME-Version: 1.0\r\n");
    printf("Content-Type: text/plain; charset=utf-8\r\n");
    printf("\r\n");  // 头结束空行

    // 邮件正文
    printf("%s\r\n", EMAIL_BODY);
    printf(".\r\n");  // 结束DATA
    read_response(250);

    // 结束连接
    printf("QUIT\r\n");
    read_response(221);

    return EXIT_SUCCESS;
}